package org.example.utils;

import io.jsonwebtoken.Claims;
import io.jsonwebtoken.Jwts;
import io.jsonwebtoken.security.Keys;
import io.jsonwebtoken.security.SecureDigestAlgorithm;

import javax.crypto.SecretKey;
import java.util.Date;
import java.util.List;

public class JwtUtils {
    //密钥字符串
    private static final String JWS_SECRET = "SFJOJWIEFJMSDFJISOJFOWOFMWOMEFOWEJFOIWEOFWOEFOWNEOFMON";
    //载荷Key
    private static final String JWS_BODY_KEY_NAME = "username";
    private static final String JWS_BODY_KEY_ID = "userId";
    private static final String JWS_BODY_KEY_AUTHORITY = "authority";
    //过期时间
    public static long EXPIRATION_TIME = 1000 * 60 * 60 * 24 * 365;
    public static long REF_EXPIRATION_TIME = 1000 * 60 * 60 * 24 * 365;
    //加密方式
    private final static SecureDigestAlgorithm<SecretKey, SecretKey> ALGORITHM = Jwts.SIG.HS256;
    //密钥串
    public static final SecretKey KEY = Keys.hmacShaKeyFor(JWS_SECRET.getBytes());


    /**
     * 根据账户生成token
     * @param username
     * @return
     */
    public static String generateToken(String username) {
        Date exprireDate = new Date(System.currentTimeMillis() + EXPIRATION_TIME);
        return Jwts.builder()
                .header()
                .add("typ", "JWT").
                and()
                .claim(JWS_BODY_KEY_NAME, username)
                .expiration(exprireDate)
                .issuedAt(new Date())
                .signWith(KEY,ALGORITHM).compact();
    }

    /**
     * 根据账户和编号生成token
     * @param username
     * @return
     */
    public static String generateToken(Integer id,String username) {
        Date exprireDate = new Date(System.currentTimeMillis() + EXPIRATION_TIME);
        return Jwts.builder().header().add("typ", "JWT").
                and().claim(JWS_BODY_KEY_NAME, username)
                .claim(JWS_BODY_KEY_ID, id)
                .expiration(exprireDate)
                .issuedAt(new Date())
                .signWith(KEY,ALGORITHM).compact();
    }

    /**
     * 根据账户和编号生成token
     * @param username
     * @return
     */
    public static String generateRefreshToken(Integer id,String username) {
        Date exprireDate = new Date(System.currentTimeMillis() + REF_EXPIRATION_TIME);
        return Jwts.builder().header().add("typ", "JWT").
                and().claim(JWS_BODY_KEY_NAME, username)
                .claim(JWS_BODY_KEY_ID, id)
                .expiration(exprireDate)
                .issuedAt(new Date())
                .signWith(KEY,ALGORITHM).compact();
    }

    /**
     * 根据账户和编号生成token
     * @param username
     * @return
     */
    public static String generateToken(Integer id, String username,
                                       List<String> authorities) {
        Date exprireDate = new Date(System.currentTimeMillis() + EXPIRATION_TIME);
        return Jwts.builder().header().add("typ", "JWT").
                and().claim(JWS_BODY_KEY_NAME, username)
                .claim(JWS_BODY_KEY_ID, id)
                .claim(JWS_BODY_KEY_AUTHORITY, authorities)
                .expiration(exprireDate)
                .issuedAt(new Date())
                .signWith(KEY,ALGORITHM).compact();
    }

    /**
     * 传递一个令牌进来之后返回一个用户名称给他
     * @param token
     * @return
     */
    public static String getUsername(String token) {
        Claims payload = Jwts.parser().verifyWith(KEY).build().parseSignedClaims(token).getPayload();
        return payload.get(JWS_BODY_KEY_NAME).toString();
    }
    /**
     * 传递一个令牌进来之后返回一个编号
     * @param token
     * @return
     */
    public static Integer getId(String token) {
        Claims payload = Jwts.parser().verifyWith(KEY).build().parseSignedClaims(token).getPayload();
        return (Integer)payload.get(JWS_BODY_KEY_ID);
    }
    /**
     * 传递一个令牌进来之后返回权限列表
     * @param token
     * @return
     */
    public static List<String> getAuthorities(String token) {
        Claims payload = Jwts.parser().verifyWith(KEY).build().parseSignedClaims(token).getPayload();
        return (List<String>) payload.get(JWS_BODY_KEY_AUTHORITY);
    }

    /**
     * 判断token是否过期
     * session
     * @param token
     * @return
     */
    public static boolean isExpired(String token) {
        Claims payload = Jwts.parser().verifyWith(KEY).build().parseSignedClaims(token).getPayload();
        return payload.getExpiration().before(new Date());
    }

    public static void main(String[] args) {

//        String encode = new BCryptPasswordEncoder().encode("123456");
//        System.out.println(encode);
        String token = generateToken(2,"admin");
        System.out.println(token);
//        String t = "eyJraWQiOiJjMWRlYzU0ZC1hOWI3LTQ0YjAtYTQ5MC1kM2YzNTc4MTQ5ZjkiLCJhbGciOiJSUzI1NiJ9.eyJzdWIiOiJhZG1pbjIiLCJhdWQiOiJjbGllbnQtYXBwIiwibmJmIjoxNzQ4MzUyMDE2LCJzY29wZSI6WyJyZWFkIiwid3JpdGUiXSwiaXNzIjoiaHR0cDovL2xvY2FsaG9zdDo5MDAwIiwiZXhwIjoxNzQ4MzUyMzE2LCJpYXQiOjE3NDgzNTIwMTYsInVzZXJJZCI6MywianRpIjoiOWFiMjNhNDAtZDZiOS00YWI1LTk0MTEtN2IzNGI2M2VjZTAyIiwiYXV0aG9yaXRpZXMiOlt7InJvbGUiOiJmaW5hbmNlOmNhcmQ6ZmluZCJ9XX0.dDPINjSCfbH_u8wTLW07td53I-BSVggq0FAYSwzmevWw_aMbt_7jDwMyQ7BY-vht-fJR84s004SxotFj_BH2ch3Le3stqFpVmMcI_j3zHTWHJ_9zJkR_0LcyE_bnf5wvL1JJnM6bo2V-iUai2NNGvcGgoVyddRCEqJDm3VEFJIvUmrSFHlu74zhwQx8zG8ga0AFr7k49PH4tFuBxvqainMq2RtcPjAYp15OCHeoGgZGr4HxbjUkDb4qSJFfJEI74NqPdKhdg0Nlqx5AzPDdwRGI8oVsqMOEHjmc7WOCGUtOUjk9Xb5fZ1sAYfbRe-1zZ9vOA10sFufdmFvgws-6NFA";
//        boolean bol = isExpired(t);
//        String username = getUsername(t);
//        System.out.println(bol);
//        System.out.println(username);

//        List<String> authorities = new ArrayList<>();
//        authorities.add("ROLE_ADMIN");
//        authorities.add("ROLE_USER");
//        authorities.add("ROLE_ROOT");
//        String token = generateToken(1,"admin",authorities);
//        String username = getUsername(token);
//        List<String> authorities1 = getAuthorities(token);
//        System.out.println(authorities1.get(1));
//        System.out.println(token);
    }
}
